home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * boxes.c
- *
- * This module implements the box primitive.
- * This file was written by Alexander Enzmann. He wrote the code for
- * boxes and generously provided us these enhancements.
- *
- * from Persistence of Vision(tm) Ray Tracer
- * Copyright 1996 Persistence of Vision Team
- *---------------------------------------------------------------------------
- * NOTICE: This source code file is provided so that users may experiment
- * with enhancements to POV-Ray and to port the software to platforms other
- * than those supported by the POV-Ray Team. There are strict rules under
- * which you are permitted to use this file. The rules are in the file
- * named POVLEGAL.DOC which should be distributed with this file. If
- * POVLEGAL.DOC is not available or for more info please contact the POV-Ray
- * Team Coordinator by leaving a message in CompuServe's Graphics Developer's
- * Forum. The latest version of POV-Ray may be found there as well.
- *
- * This program is based on the popular DKB raytracer version 2.12.
- * DKBTrace was originally written by David K. Buck.
- * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
- *
- *****************************************************************************/
-
- #include "frame.h"
- #include "povray.h"
- #include "vector.h"
- #include "povproto.h"
- #include "bbox.h"
- #include "boxes.h"
- #include "matrices.h"
- #include "objects.h"
-
-
-
- /*****************************************************************************
- * Local preprocessor defines
- ******************************************************************************/
-
- /* Minimal intersection depth. */
-
- #define DEPTH_TOLERANCE 1.0e-6
-
- /* Two values are equal if their difference is small than CLOSE_TOLERANCE. */
-
- #define CLOSE_TOLERANCE 1.0e-6
-
- /* Side hit. */
-
- #define SIDE_X_0 1
- #define SIDE_X_1 2
- #define SIDE_Y_0 3
- #define SIDE_Y_1 4
- #define SIDE_Z_0 5
- #define SIDE_Z_1 6
-
-
-
- /*****************************************************************************
- * Static functions
- ******************************************************************************/
- static int All_Box_Intersections PARAMS((OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack));
- static int Inside_Box PARAMS((VECTOR point, OBJECT *Object));
- static void Box_Normal PARAMS((VECTOR Result, OBJECT *Object, INTERSECTION *Inter));
- static void Translate_Box PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
- static void Rotate_Box PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
- static void Scale_Box PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
- static void Transform_Box PARAMS((OBJECT *Object, TRANSFORM *Trans));
- static void Invert_Box PARAMS((OBJECT *Object));
-
-
-
- /*****************************************************************************
- * Local variables
- ******************************************************************************/
-
- METHODS Box_Methods =
- {
- All_Box_Intersections,
- Inside_Box, Box_Normal,
- Copy_Box, Translate_Box, Rotate_Box, Scale_Box, Transform_Box,
- Invert_Box, Destroy_Box
- };
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * All_Box_Intersections
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Alexander Enzmann
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static int All_Box_Intersections(Object, Ray, Depth_Stack)
- OBJECT *Object;
- RAY *Ray;
- ISTACK *Depth_Stack;
- {
- int Intersection_Found;
- int Side1, Side2;
- DBL Depth1, Depth2;
- VECTOR IPoint;
-
- Increase_Counter(stats[Ray_Box_Tests]);
-
- Intersection_Found = FALSE;
-
- if (Intersect_Box(Ray, (BOX *)Object, &Depth1, &Depth2, &Side1, &Side2))
- {
- if (Depth1 > DEPTH_TOLERANCE)
- {
- VEvaluateRay(IPoint, Ray->Initial, Depth1, Ray->Direction);
-
- if (Point_In_Clip(IPoint, Object->Clip))
- {
- push_entry_i1(Depth1,IPoint,Object,Side1,Depth_Stack);
-
- Intersection_Found = TRUE;
- }
- }
-
- VEvaluateRay(IPoint, Ray->Initial, Depth2, Ray->Direction);
-
- if (Point_In_Clip(IPoint, Object->Clip))
- {
- push_entry_i1(Depth2,IPoint,Object,Side2,Depth_Stack);
-
- Intersection_Found = TRUE;
- }
- }
-
- if (Intersection_Found)
- {
- Increase_Counter(stats[Ray_Box_Tests_Succeeded]);
- }
-
- return (Intersection_Found);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Intersect_Box
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Alexander Enzmann
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * Sep 1994 : Added code to decide which side was hit in the case
- * intersection points are close to each other. This removes
- * some ugly artefacts one could observe at the corners of
- * boxes due to the usage of the wrong normal vector. [DB]
- *
- ******************************************************************************/
-
- int Intersect_Box(Ray, box, Depth1, Depth2, Side1, Side2)
- RAY *Ray;
- BOX *box;
- DBL *Depth1, *Depth2;
- int *Side1, *Side2;
- {
- int smin = 0, smax = 0; /* Side hit for min/max intersection. */
- DBL t, tmin, tmax;
- VECTOR P, D;
- DBL rdivx;
- DBL rdivy;
- DBL rdivz;
-
- /* Transform the point into the boxes space */
-
- if (box->Trans != NULL)
- {
- MInvTransPoint(P, Ray->Initial, box->Trans);
- MInvTransDirection(D, Ray->Direction, box->Trans);
- }
- else
- {
- Assign_Vector(P, Ray->Initial);
- Assign_Vector(D, Ray->Direction);
- }
-
- tmin = 0.0;
- tmax = BOUND_HUGE;
-
- /*
- * Sides first.
- */
-
- rdivx = (1.0 / D[X]);
- rdivy = (1.0 / D[Y]);
- rdivz = (1.0 / D[Z]);
-
- if (D[X] < -EPSILON)
- {
- /*
- t = (box->bounds[0][X] - P[X]) / D[X];
- */
- t = (box->bounds[0][X] - P[X]) * rdivx;
-
- if (t < tmin) return(FALSE);
-
- if (t <= tmax)
- {
- smax = SIDE_X_0;
- tmax = t;
- }
-
- /*
- t = (box->bounds[1][X] - P[X]) / D[X];
- */
- t = (box->bounds[1][X] - P[X]) * rdivx;
-
- if (t >= tmin)
- {
- if (t > tmax) return(FALSE);
-
- smin = SIDE_X_1;
- tmin = t;
- }
- }
- else
- {
- if (D[X] > EPSILON)
- {
- /*
- t = (box->bounds[1][X] - P[X]) / D[X];
- */
- t = (box->bounds[1][X] - P[X]) * rdivx;
-
- if (t < tmin) return(FALSE);
-
- if (t <= tmax)
- {
- smax = SIDE_X_1;
- tmax = t;
- }
-
- /*
- t = (box->bounds[0][X] - P[X]) / D[X];
- */
- t = (box->bounds[0][X] - P[X]) * rdivx;
-
- if (t >= tmin)
- {
- if (t > tmax) return(FALSE);
-
- smin = SIDE_X_0;
- tmin = t;
- }
- }
- else
- {
- if ((P[X] < box->bounds[0][X]) || (P[X] > box->bounds[1][X]))
- {
- return(FALSE);
- }
- }
- }
-
- /*
- * Check Top/Bottom.
- */
-
- if (D[Y] < -EPSILON)
- {
- /*
- t = (box->bounds[0][Y] - P[Y]) / D[Y];
- */
- t = (box->bounds[0][Y] - P[Y]) * rdivy;
-
- if (t < tmin) return(FALSE);
-
- if (t <= tmax - CLOSE_TOLERANCE)
- {
- smax = SIDE_Y_0;
- tmax = t;
- }
- else
- {
- /*
- * If intersection points are close to each other find out
- * which side to use, i.e. is most probably hit. [DB 9/94]
- */
-
- if (t <= tmax + CLOSE_TOLERANCE)
- {
- if (-D[Y] > fabs(D[X])) smax = SIDE_Y_0;
- }
- }
-
- /*
- t = (box->bounds[1][Y] - P[Y]) / D[Y];
- */
- t = (box->bounds[1][Y] - P[Y]) * rdivy;
-
- if (t >= tmin + CLOSE_TOLERANCE)
- {
- if (t > tmax) return(FALSE);
-
- smin = SIDE_Y_1;
- tmin = t;
- }
- else
- {
- /*
- * If intersection points are close to each other find out
- * which side to use, i.e. is most probably hit. [DB 9/94]
- */
-
- if (t >= tmin - CLOSE_TOLERANCE)
- {
- if (-D[Y] > fabs(D[X])) smin = SIDE_Y_1;
- }
- }
- }
- else
- {
- if (D[Y] > EPSILON)
- {
-
- /*
- t = (box->bounds[1][Y] - P[Y]) / D[Y];
- */
- t = (box->bounds[1][Y] - P[Y]) * rdivy;
-
- if (t < tmin) return(FALSE);
-
- if (t <= tmax - CLOSE_TOLERANCE)
- {
- smax = SIDE_Y_1;
- tmax = t;
- }
- else
- {
- /*
- * If intersection points are close to each other find out
- * which side to use, i.e. is most probably hit. [DB 9/94]
- */
-
- if (t <= tmax + CLOSE_TOLERANCE)
- {
- if (D[Y] > fabs(D[X])) smax = SIDE_Y_1;
- }
- }
-
- /*
- t = (box->bounds[0][Y] - P[Y]) / D[Y];
- */
- t = (box->bounds[0][Y] - P[Y]) * rdivy;
-
- if (t >= tmin + CLOSE_TOLERANCE)
- {
- if (t > tmax) return(FALSE);
-
- smin = SIDE_Y_0;
- tmin = t;
- }
- else
- {
- /*
- * If intersection points are close to each other find out
- * which side to use, i.e. is most probably hit. [DB 9/94]
- */
-
- if (t >= tmin - CLOSE_TOLERANCE)
- {
- if (D[Y] > fabs(D[X])) smin = SIDE_Y_0;
- }
- }
- }
- else
- {
- if ((P[Y] < box->bounds[0][Y]) || (P[Y] > box->bounds[1][Y]))
- {
- return(FALSE);
- }
- }
- }
-
- /* Now front/back */
-
- if (D[Z] < -EPSILON)
- {
-
- /*
- t = (box->bounds[0][Z] - P[Z]) / D[Z];
- */
- t = (box->bounds[0][Z] - P[Z]) * rdivz;
-
- if (t < tmin) return(FALSE);
-
- if (t <= tmax - CLOSE_TOLERANCE)
- {
- smax = SIDE_Z_0;
- tmax = t;
- }
- else
- {
- /*
- * If intersection points are close to each other find out
- * which side to use, i.e. is most probably hit. [DB 9/94]
- */
-
- if (t <= tmax + CLOSE_TOLERANCE)
- {
- switch (smax)
- {
- case SIDE_X_0 :
- case SIDE_X_1 : if (-D[Z] > fabs(D[X])) smax = SIDE_Z_0; break;
-
- case SIDE_Y_0 :
- case SIDE_Y_1 : if (-D[Z] > fabs(D[Y])) smax = SIDE_Z_0; break;
- }
- }
- }
-
- /*
- t = (box->bounds[1][Z] - P[Z]) / D[Z];
- */
- t = (box->bounds[1][Z] - P[Z]) * rdivz;
-
- if (t >= tmin + CLOSE_TOLERANCE)
- {
- if (t > tmax) return(FALSE);
-
- smin = SIDE_Z_1;
- tmin = t;
- }
- else
- {
- /*
- * If intersection points are close to each other find out
- * which side to use, i.e. is most probably hit. [DB 9/94]
- */
-
- if (t >= tmin - CLOSE_TOLERANCE)
- {
- switch (smin)
- {
- case SIDE_X_0 :
- case SIDE_X_1 : if (-D[Z] > fabs(D[X])) smin = SIDE_Z_1; break;
-
- case SIDE_Y_0 :
- case SIDE_Y_1 : if (-D[Z] > fabs(D[Y])) smin = SIDE_Z_1; break;
- }
- }
- }
- }
- else
- {
- if (D[Z] > EPSILON)
- {
-
- /*
- t = (box->bounds[1][Z] - P[Z]) / D[Z];
- */
- t = (box->bounds[1][Z] - P[Z]) * rdivz;
-
- if (t < tmin) return(FALSE);
-
- if (t <= tmax - CLOSE_TOLERANCE)
- {
- smax = SIDE_Z_1;
- tmax = t;
- }
- else
- {
- /*
- * If intersection points are close to each other find out
- * which side to use, i.e. is most probably hit. [DB 9/94]
- */
-
- if (t <= tmax + CLOSE_TOLERANCE)
- {
- switch (smax)
- {
- case SIDE_X_0 :
- case SIDE_X_1 : if (D[Z] > fabs(D[X])) smax = SIDE_Z_1; break;
-
- case SIDE_Y_0 :
- case SIDE_Y_1 : if (D[Z] > fabs(D[Y])) smax = SIDE_Z_1; break;
- }
- }
- }
-
- /*
- t = (box->bounds[0][Z] - P[Z]) / D[Z];
- */
- t = (box->bounds[0][Z] - P[Z]) * rdivz;
-
- if (t >= tmin + CLOSE_TOLERANCE)
- {
- if (t > tmax) return(FALSE);
-
- smin = SIDE_Z_0;
- tmin = t;
- }
- else
- {
- /*
- * If intersection points are close to each other find out
- * which side to use, i.e. is most probably hit. [DB 9/94]
- */
-
- if (t >= tmin - CLOSE_TOLERANCE)
- {
- switch (smin)
- {
- case SIDE_X_0 :
- case SIDE_X_1 : if (D[Z] > fabs(D[X])) smin = SIDE_Z_0; break;
-
- case SIDE_Y_0 :
- case SIDE_Y_1 : if (D[Z] > fabs(D[Y])) smin = SIDE_Z_0; break;
- }
- }
- }
- }
- else
- {
- if ((P[Z] < box->bounds[0][Z]) || (P[Z] > box->bounds[1][Z]))
- {
- return(FALSE);
- }
- }
- }
-
- if (tmax < DEPTH_TOLERANCE)
- {
- return (FALSE);
- }
-
- *Depth1 = tmin;
- *Depth2 = tmax;
-
- *Side1 = smin;
- *Side2 = smax;
-
- return(TRUE);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Inside_Box
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Alexander Enzmann
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static int Inside_Box(IPoint, Object)
- VECTOR IPoint;
- OBJECT *Object;
- {
- VECTOR New_Point;
- BOX *box = (BOX *) Object;
-
- /* Transform the point into box space. */
-
- if (box->Trans != NULL)
- {
- MInvTransPoint(New_Point, IPoint, box->Trans);
- }
- else
- {
- Assign_Vector(New_Point,IPoint);
- }
-
- /* Test to see if we are outside the box. */
-
- if ((New_Point[X] < box->bounds[0][X]) || (New_Point[X] > box->bounds[1][X]))
- {
- return (Test_Flag(box, INVERTED_FLAG));
- }
-
- if ((New_Point[Y] < box->bounds[0][Y]) || (New_Point[Y] > box->bounds[1][Y]))
- {
- return (Test_Flag(box, INVERTED_FLAG));
- }
-
- if ((New_Point[Z] < box->bounds[0][Z]) || (New_Point[Z] > box->bounds[1][Z]))
- {
- return (Test_Flag(box, INVERTED_FLAG));
- }
-
- /* Inside the box. */
-
- return (!Test_Flag(box, INVERTED_FLAG));
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Box_Normal
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Alexander Enzmann
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Box_Normal(Result, Object, Inter)
- OBJECT *Object;
- VECTOR Result;
- INTERSECTION *Inter;
- {
- switch (Inter->i1)
- {
- case SIDE_X_0: Make_Vector(Result, -1.0, 0.0, 0.0); break;
- case SIDE_X_1: Make_Vector(Result, 1.0, 0.0, 0.0); break;
- case SIDE_Y_0: Make_Vector(Result, 0.0, -1.0, 0.0); break;
- case SIDE_Y_1: Make_Vector(Result, 0.0, 1.0, 0.0); break;
- case SIDE_Z_0: Make_Vector(Result, 0.0, 0.0, -1.0); break;
- case SIDE_Z_1: Make_Vector(Result, 0.0, 0.0, 1.0); break;
-
- default: Error("Unknown box side in Box_Normal().\n");
- }
-
- /* Transform the point into the boxes space. */
-
- if (((BOX *)Object)->Trans != NULL)
- {
- MTransNormal(Result, Result, ((BOX *)Object)->Trans);
-
- VNormalize(Result, Result);
- }
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Translate_Box
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Alexander Enzmann
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Translate_Box(Object, Vector, Trans)
- OBJECT *Object;
- VECTOR Vector;
- TRANSFORM *Trans;
- {
- if (((BOX *)Object)->Trans == NULL)
- {
- VAddEq(((BOX *)Object)->bounds[0], Vector);
-
- VAddEq(((BOX *)Object)->bounds[1], Vector);
-
- Compute_Box_BBox((BOX *)Object);
- }
- else
- {
- Transform_Box(Object, Trans);
- }
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Rotate_Box
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Alexander Enzmann
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Rotate_Box(Object, Vector, Trans)
- OBJECT *Object;
- VECTOR Vector;
- TRANSFORM *Trans;
- {
- Transform_Box(Object, Trans);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Scale_Box
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Alexander Enzmann
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Scale_Box(Object, Vector, Trans)
- OBJECT *Object;
- VECTOR Vector;
- TRANSFORM *Trans;
- {
- DBL temp;
- BOX *Box = (BOX *)Object;
-
- if (((BOX *)Object)->Trans == NULL)
- {
- VEvaluateEq(Box->bounds[0], Vector);
- VEvaluateEq(Box->bounds[1], Vector);
-
- if (Box->bounds[0][X] > Box->bounds[1][X])
- {
- temp = Box->bounds[0][X];
-
- Box->bounds[0][X] = Box->bounds[1][X];
- Box->bounds[1][X] = temp;
- }
-
- if (Box->bounds[0][Y] > Box->bounds[1][Y])
- {
- temp = Box->bounds[0][Y];
-
- Box->bounds[0][Y] = Box->bounds[1][Y];
- Box->bounds[1][Y] = temp;
- }
-
- if (Box->bounds[0][Z] > Box->bounds[1][Z])
- {
- temp = Box->bounds[0][Z];
-
- Box->bounds[0][Z] = Box->bounds[1][Z];
- Box->bounds[1][Z] = temp;
- }
-
- Compute_Box_BBox((BOX *)Object);
- }
- else
- {
- Transform_Box(Object, Trans);
- }
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Invert_Box
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Alexander Enzmann
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Invert_Box(Object)
- OBJECT *Object;
- {
- Invert_Flag(Object, INVERTED_FLAG);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Transform_Box
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Alexander Enzmann
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void Transform_Box(Object, Trans)
- OBJECT *Object;
- TRANSFORM *Trans;
- {
- BOX *box = (BOX *)Object;
-
- if (box->Trans == NULL)
- {
- box->Trans = Create_Transform();
- }
-
- Compose_Transforms(box->Trans, Trans);
-
- Compute_Box_BBox(box);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Create_Box
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Alexander Enzmann
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- BOX *Create_Box()
- {
- BOX *New;
-
- New = (BOX *)POV_MALLOC(sizeof(BOX), "box");
-
- INIT_OBJECT_FIELDS(New, BOX_OBJECT, &Box_Methods)
-
- Make_Vector(New->bounds[0], -1.0, -1.0, -1.0);
- Make_Vector(New->bounds[1], 1.0, 1.0, 1.0);
-
- Make_BBox(New->BBox, -1.0, -1.0, -1.0, 2.0, 2.0, 2.0);
-
- New->Trans = NULL;
-
- return (New);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Copy_Box
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Alexander Enzmann
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- void *Copy_Box(Object)
- OBJECT *Object;
- {
- BOX *New;
-
- New = Create_Box();
-
- /* Copy box. */
-
- *New = *((BOX *)Object);
-
- New->Trans = Copy_Transform(((BOX *)Object)->Trans);
-
- return (New);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Destroy_Box
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Alexander Enzmann
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- void Destroy_Box(Object)
- OBJECT *Object;
- {
- Destroy_Transform(((BOX *)Object)->Trans);
-
- POV_FREE (Object);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Compute_Box_BBox
- *
- * INPUT
- *
- * Box - Box
- *
- * OUTPUT
- *
- * Box
- *
- * RETURNS
- *
- * AUTHOR
- *
- * Dieter Bayer
- *
- * DESCRIPTION
- *
- * Calculate the bounding box of a box.
- *
- * CHANGES
- *
- * Aug 1994 : Creation.
- *
- ******************************************************************************/
-
- void Compute_Box_BBox(Box)
- BOX *Box;
- {
- Assign_BBox_Vect(Box->BBox.Lower_Left, Box->bounds[0]);
-
- VSub(Box->BBox.Lengths, Box->bounds[1], Box->bounds[0]);
-
- if (Box->Trans != NULL)
- {
- Recompute_BBox(&Box->BBox, Box->Trans);
- }
- }
-
-